import {
	BadRequestException,
	HttpCode,
	HttpException,
	HttpStatus,
	Inject,
	Injectable,
	UnauthorizedException,
} from "@nestjs/common";
import { CreateUserDto } from "./dto/create-user.dto";
import { PrismaService } from "@/common/prisma/prisma.service";
import { handleError } from "@/utils/handle.error";
import { LoggerService } from "@/common/logger/logger.service";
import { hash, compare } from "bcryptjs";
import { UpdateUserDto } from "./dto/update-user.dto";
import { RedisService } from "@/common/redis/redis.service";
import { RedisKeyEnum } from "@/common/enums/redis-key.enum";
@Injectable()
export class UserService {
	@Inject(LoggerService)
	private readonly logger: LoggerService;

	@Inject(PrismaService)
	private readonly prismaService: PrismaService;

	@Inject(RedisService)
	private readonly redisService: RedisService;

	async register(createUserDto: CreateUserDto) {
		this.logger.log(`${this.register.name} was called`);
		try {
			const { name, password, phone, avatar, email } = createUserDto;
			const saltPwd = await hash(password, 10);
			const data = await this.prismaService.user.findFirst({
				where: {
					OR: [
						{
							name,
						},
						{
							phone,
						},
					],
				},
			});
			if (data) {
				let msg = "已存在";
				if (phone === data.phone) {
					msg = `手机号${phone}${msg}`;
				}
				if (name === data.name) {
					msg = `用户名${name}${msg}`;
				}
				throw new BadRequestException(msg);
			}
			const { id } = await this.prismaService.user.create({
				data: { name, phone, avatar, email, password: saltPwd },
				select: {
					id: true,
				},
			});
			return id;
		} catch (error) {
			handleError(this.logger, error, {
				common: "创建用户失败",
			});
		}
	}

	async findUserById(id: number) {
		this.logger.log(`${this.findUserById.name} was called`);
		try {
			const user = await this.prismaService.user.findUnique({
				where: { id, isDelete: false },
				select: {
					id: true,
					name: true,
					avatar: true,
					phone: true,
					email: true,
					openid: true,
				},
			});
			if (!user) throw new BadRequestException("该用户不存在");
			return user;
		} catch (error) {
			handleError(this.logger, error, {
				common: "查找用户失败",
			});
		}
	}

	/** 通过名称批量查询openid */
	async getOpenidList(names: string) {
		this.logger.log(`${this.getOpenidList.name} was called`);
		try {
			if (!names) {
				throw new BadRequestException("names字段不能为空");
			}
			const nameList = names.split(",").filter(Boolean);
			// 使用 Prisma 查询匹配的 openid
			const users = await this.prismaService.user.findMany({
				where: {
					name: {
						in: nameList, // 匹配 name 在 nameList 中的记录
					},
				},
				select: {
					openid: true, // 仅获取 openid 字段
				},
			});
			// 提取 openid 生成数组
			return users.map((user) => user.openid);
		} catch (error) {
			handleError(this.logger, error, {
				common: "批量查询openid失败",
			});
		}
	}

	async updateUser(updateUserDto: UpdateUserDto) {
		this.logger.log(`${this.updateUser.name} was called`);
		try {
			const { id, name, avatar, phone, email, openid } = updateUserDto;
			const findUser = await this.findUserById(id);
			if (!findUser) throw new HttpException("用户不存在", HttpStatus.OK);
			const user = await this.prismaService.user.update({
				where: {
					id,
					isDelete: false,
				},
				data: {
					name,
					avatar,
					phone,
					email,
					openid,
				},
			});
			return user;
		} catch (error) {
			handleError(this.logger, error, {
				common: "更新用户失败",
			});
		}
	}

	async validateUserByPwd(name: string, password: string) {
		this.logger.log(`${this.validateUserByPwd.name} was called`);
		try {
			// 查找用户
			const user = await this.prismaService.user.findUnique({
				select: {
					id: true,
					name: true,
					password: true,
					email: true,
					phone: true,
					avatar: true,
				},
				where: {
					name,
					isDelete: false,
				},
			});
			// 判断用户是否存在
			if (!user) throw new UnauthorizedException("用户不存在");
			// 判断密码是否正确
			const isPwdValid = await compare(password, user.password);
			//密码不正确
			if (!isPwdValid) throw new UnauthorizedException("账号或密码错误");
			const { password: _password, ...result } = user;
			return result;
		} catch (error) {
			handleError(this.logger, error, {
				common: "验证用户失败",
			});
		}
	}

	async validateUserByEmail(email: string, code: string) {
		this.logger.log(`${this.validateUserByEmail.name} was called`);
		try {
			const redisCode = await this.redisService._get(
				RedisKeyEnum.LoginKey + email,
			);
			if (!redisCode) {
				throw new HttpException(
					"验证码不存在，请输入正确验证码",
					HttpStatus.OK,
				);
			}
			if (redisCode && redisCode !== code) {
				throw new HttpException("验证码错误，请重新输入", HttpStatus.OK);
			}
			// 查找用户
			const user = await this.prismaService.user.findFirst({
				select: {
					id: true,
					name: true,
					password: true,
					email: true,
					phone: true,
					avatar: true,
				},
				where: {
					email,
					isDelete: false,
				},
			});
			// 判断用户是否存在
			if (!user) throw new UnauthorizedException("用户不存在");
			return user;
		} catch (error) {
			handleError(this.logger, error, {
				common: "验证用户失败",
			});
		}
	}

	/**
	 * 记录用户ip
	 * @param id 用户id
	 * @param ip 用户ip
	 * @returns
	 */
	async recordUserIp(id: number, ip: string) {
		this.logger.log(`${this.recordUserIp.name} was called`);
		try {
			await this.prismaService.user.update({
				where: { id },
				data: { ip },
			});
		} catch (error) {
			handleError(this.logger, error, { common: "记录用户ip失败" });
		}
	}
}
